在上一篇成功實作最基本的WebFlux
功能,看到了一些有點熟悉又有點陌生的新朋友,在這邊補充說明。
Spring 同樣保留了支援annotation-based
,依然可以使用熟悉的Spring MVC
各式annotation(@RequestMapping
、@RestController
...),那為什麼需要有Handler
&Router
?
首先如果你對原本的annotation
感到十分親切,當然可以繼續採用原本的寫法,一樣直覺好用,但畢竟Reactive我們希望能夠Functional
,所以如果是一個新的專案想要嘗試Reactive Spring
,那擁抱Functional
的Handler
&Router
是一個不錯的選擇。
ServerResponse
類似以前的ResponseEntity
,含有status
、header
、body
,提供了更多方法更加的Functional
。ServerRequest
在原有的Spring MVC
當中並沒有這樣的角色,Spring
透過各式annotation(@RequestMapping
、@Valid
)自動幫你帶入指定的Object
,雖然非常方便,但其實如果你沒有深入去了解,是沒辦法從程式碼去連結到行為與資料(都是背後處理掉),而且不容易繼承來進行客製化,annotation如果要取得路徑或是其他資料需要透過反射(reflection
),相對就會有效能與type erasure
的問題,ServerRequest
與ServerResponse
改為Functional
的風格則會讓過程更佳清楚。
public class PersonHandler {
private final PersonRepository repository;
public PersonHandler(PersonRepository repository) {
this.repository = repository;
}
public Mono<ServerResponse> listPeople(ServerRequest request) {
Flux<Person> people = repository.allPeople();
return ok().contentType(APPLICATION_JSON).body(people, Person.class);
}
public Mono<ServerResponse> createPerson(ServerRequest request) {
Mono<Person> person = request.bodyToMono(Person.class);
return ok().build(repository.savePerson(person));
}
public Mono<ServerResponse> getPerson(ServerRequest request) {
int personId = Integer.valueOf(request.pathVariable("id"));
return repository.getPerson(personId)
.flatMap(person -> ok().contentType(APPLICATION_JSON).bodyValue(person))
.switchIfEmpty(ServerResponse.notFound().build());
}
}
類似於RestTemplate
,是一個functional的Api,支援non-blocking/blocking、streaming,寫起來更加的流暢。透過Codecs
來處理(serializing
/deserializing
)我們需要使用的物件,Codecs
同樣類似於Spring MVC
的HttpMessageConverter
。
WebClient webClient = WebClient.builder()
.codecs(configurer -> {
CustomDecoder decoder = new CustomDecoder();
configurer.customCodecs().registerWithDefaultConfig(decoder);
})
.build();
透過ntellij
動demo專案時發生一個錯誤,推測可能是啟動JMX(管理JVM的內的entity,視覺化的呈現)時pringApplication
未開啟完成導致
javax.management.InstanceNotFoundException: org.springframework.boot:type=Admin,name=SpringApplication
參考stackoverflow回答則可正常執行https://stackoverflow.com/questions/50436108/javax-management-instancenotfoundexception-org-springframework-boottype-admin
接下來會稍微深入一點來看Handler&Router。
開始到了文章越來越難產的一個階段,最後八篇!